/**********************************************
* @file    	bitband.h
* @author 	dralee
* @version	v1.0
* @date		2021-11-30
* @brief	位带操作
*		SRAM位带区：0x2000 0000~0x2010 0000
*	SRAM位带别名区：0x2200 0000~0x23FF FFFF
*		外设位带区：0x4000 0000~0x4010 0000
*	外设位带别名区：0x4200 0000~0x43FF FFFF
***********************************************/
#ifndef __BITBAND__H
#define __BITBAND__H

#include "stm32f10x.h"

/**
 *****************************************
 * @brief 把“位带地址+位序号”转换成别名地址宏
 *	addr & 0xF000000，取地址高4位，结果是2还是4，用于区分SRAM和外设地址
 *	  为2，+0x02000000则=0x2200 0000，即SRAM，如为4，+0x02000000则=0x4200 0000，为外设
 *	addr & 0x00FFFFFF，屏蔽掉高两位，相当于-0x2000 0000或-0x4000 0000，结果表示偏移位带区多少字节
 * 	<<5 等于*8*4，因位带区一个地址表示一个字节，一个字节8位，一个位可膨胀成一个字，即4个字节
 *	<<2 等于*4，因一个位可膨胀成一个字，即4个字节
 *	分解成两条公式为：
 *	  SRAM位带别名地址
 *		AliasAddr= 0x22000000+((A-0x20000000)*8+n)*4 =0x22000000+ (A-0x20000000)*8*4 +n*4
 *	  外设位带别名地址
 *		AliasAddr= 0x22000000+((A-0x20000000)*8+n)*4 =0x22000000+ (A-0x20000000)*8*4 +n*4
 *
 * @param addr 位带地址
 * @param bitnum 位序号0~7
 * @retval 别名地址 
 *****************************************/
#define BIT_BAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))

/**
 *****************************************
 * @brief 把一个地址转换成一个指针
 * @param addr 地址
 * @retval 地址指针
 *****************************************/
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
	
/**
 *****************************************
* @brief 把位带别名区地址转换成指针
* @param addr 位带别名区地址
 * @retval 地址指针
 *****************************************/
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BIT_BAND(addr, bitnum))

// GPIO ODR和IDR寄存器地址映射
#define GPIOA_ODR_Addr	(GPIOA_BASE+12)	// 0x4001080C
#define GPIOB_ODR_Addr	(GPIOB_BASE+12)	// 0x40010C0C
#define GPIOC_ODR_Addr	(GPIOC_BASE+12)	// 0x4001100C
#define GPIOD_ODR_Addr	(GPIOD_BASE+12)	// 0x4001140C
#define GPIOE_ODR_Addr	(GPIOE_BASE+12)	// 0x4001180C
#define GPIOF_ODR_Addr	(GPIOF_BASE+12)	// 0x40011A0C
#define GPIOG_ODR_Addr	(GPIOG_BASE+12)	// 0x40011E0C

#define GPIOA_IDR_Addr	(GPIOA_BASE+8)	// 0x40010808
#define GPIOB_IDR_Addr	(GPIOB_BASE+8)	// 0x40010C08
#define GPIOC_IDR_Addr	(GPIOC_BASE+8)	// 0x40011008
#define GPIOD_IDR_Addr	(GPIOD_BASE+8)	// 0x40011408
#define GPIOE_IDR_Addr	(GPIOE_BASE+8)	// 0x40011808
#define GPIOF_IDR_Addr	(GPIOF_BASE+8)	// 0x40011A08
#define GPIOG_IDR_Addr	(GPIOG_BASE+8)	// 0x40011E08

// 单独操作GPIO某一个IO口，n(0~15)
#define PAout(n)	BIT_ADDR(GPIOA_ODR_Addr, n)	// 输出
#define PBout(n)	BIT_ADDR(GPIOB_ODR_Addr, n)	// 输出
#define PCout(n)	BIT_ADDR(GPIOC_ODR_Addr, n)	// 输出
#define PDout(n)	BIT_ADDR(GPIOD_ODR_Addr, n)	// 输出
#define PEout(n)	BIT_ADDR(GPIOE_ODR_Addr, n)	// 输出
#define PFout(n)	BIT_ADDR(GPIOF_ODR_Addr, n)	// 输出
#define PGout(n)	BIT_ADDR(GPIOG_ODR_Addr, n)	// 输出

#define PAin(n)		BIT_ADDR(GPIOA_IDR_Addr, n)	// 输入
#define PBin(n)		BIT_ADDR(GPIOB_IDR_Addr, n)	// 输入
#define PCin(n)		BIT_ADDR(GPIOC_IDR_Addr, n)	// 输入
#define PDin(n)		BIT_ADDR(GPIOD_IDR_Addr, n)	// 输入
#define PEin(n)		BIT_ADDR(GPIOE_IDR_Addr, n)	// 输入
#define PFin(n)		BIT_ADDR(GPIOF_IDR_Addr, n)	// 输入
#define PGin(n)		BIT_ADDR(GPIOG_IDR_Addr, n)	// 输入


#endif // --end __BITBAND__H
